import React, { lazy, Suspense, useContext, useEffect, useMemo, useState } from 'react';
import { IBelong } from '@/ts/core';
import { Badge, Button, Dropdown, message, Space, Tabs } from 'antd';
import { XSheet, XValidation } from '@/ts/base/schema';
import { command, model, schema } from '@/ts/base';
import WorkFormService from '@/ts/scripting/core/services/WorkFormService';
import useAsyncLoad from '@/hooks/useAsyncLoad';
import { getAggregationDate } from '../Utils/index';
import { mapErrorToValidateInfo } from '@/ts/scripting/js/util';
import { AssignTaskContext } from '@/components/DataPreview/assign';
import Icon, { MoreOutlined } from '@ant-design/icons';
import { EditModal } from '@/executor/tools/editModal';
import LoadingView from '@/components/Common/Loading';
import { NodeType } from '@/ts/base/enum';
import * as icons from '@ant-design/icons';
import { getUuid } from '@/utils/tools';
import { AssignFillData } from '@/components/DataPreview/assign/assignFillData';
import orgCtrl from '@/ts/controller';
import { $confirm } from '@/utils/react/antd';
import { ValidationModal } from '@/components/Common/Validate/ValidationModal';

const HotTableView = lazy(() => import('./hotTable'));

interface IProps {
  data: { [key: string]: any };
  allowEdit: boolean;
  belong: IBelong;
  form: schema.XReport;
  info?: model.FormInfo;
  readonly?: boolean;
  showTitle?: boolean;
  fields: model.FieldModel[];
  rules: model.RenderRule[];
  formData?: model.FormEditData;
  primary: {
    [id: string]: any;
  };
  onValuesChange?: (fieldId: string, value: any, data: any, coord?: any) => void;
  activeTabKey?: string;
  height?: string;
  service: WorkFormService;
}

const WorkReportViewer: React.FC<IProps> = (props) => {
  const [sheetList, setSheetList] = useState<XSheet[]>([]);
  const [activeKey, setActiveKey] = useState<string>();
  const [variablesData, setVariablesData] = useState<any>();
  const [reportHeight, setReportHeight] = useState<any>();
  const [btnType, setBtnType] = useState<string>();
  const [fillDataVisible, setFillDataVisible] = useState<boolean>(false);
  const [errorCount, setErrorCount] = useState(0);
  const [validates, setValidates] = useState<XValidation[]>([]);
  const [validateVisible, setValidateVisible] = useState(false);

  useEffect(() => {
    const sheetListData: XSheet[] = Object.values(props.form?.sheets || {});
    setSheetList(sheetListData);
    if (sheetListData.length > 0) {
      setActiveKey(sheetListData[0]?.code);
    }
    setReportHeight(props.height || 'calc(100vh - 220px)');
  }, [props.form, props.height]);

  const assignTask = useContext(AssignTaskContext);

  const [loaded] = useAsyncLoad(async () => {
    await getVariableData();
    props.form.cacheValue = props.form.cacheValue || {};
    Object.keys(props.form.sheets).forEach((key) => {
      const sheet = props.form.sheets[key];
      if (sheet && sheet.code && sheet.code !== 'variableSheet') {
        props.form.cacheValue[sheet.code] = {};
      }
      sheet.sheetConfig.floatRowsSetting?.forEach((setting) => {
        if (setting && setting.floatRowCode) {
          props.form.cacheValue[setting.floatRowCode] = [];
        }
      });
    });
    props.service.updateReportData(props.form.cacheValue);
    console.warn(props.service.model);
    setValidates(props.service.model?.validation || []);
  }, [props.form]);

  const getVariableData = async () => {
    let variableData: any = {};
    if (!props.readonly) {
      const variables = props.form.variables ?? {};
      const promises = Object.keys(variables).map(async (key) => {
        if (variables[key].value?.type === '取数型') {
          variableData[key] = await getAggregationDate(
            variables[key].value?.valueString,
            props.belong,
          );
        }
      });
      await Promise.all(promises);
    }
    setVariablesData(variableData);
  };
  const tabItems = useMemo(() => {
    return sheetList
      .filter((sheet) => sheet.code !== 'variableSheet')
      .filter((sheet) => {
        if (props.service.model.assignTask?.nodeType && sheet.category !== undefined) {
          return props.service.model.assignTask.nodeType === sheet.category;
        }
        if (assignTask?.metadata.nodeType != undefined && sheet.category !== undefined) {
          return assignTask.metadata.nodeType === sheet.category;
        }
        return true;
      })
      .map((sheet) => ({
        key: sheet.code,
        label: sheet.icon ? (
          <>
            <Icon component={icons[sheet.icon[0]]} style={{ marginRight: '0px' }} />
            {sheet.name}
          </>
        ) : (
          sheet.name
        ),
        forceRender: true,
        children: (
          <>
            <Suspense
              fallback={
                <div className="loading-page">
                  <LoadingView text="信息加载中..." />
                </div>
              }>
              <HotTableView
                {...props}
                height={reportHeight || 'calc(100vh - 220px)'}
                sheet={sheet}
                variablesData={variablesData}
                activeKey={activeKey}
                btnType={btnType}
              />
            </Suspense>
            {fillDataVisible && assignTask && (
              <AssignFillData
                assignTask={assignTask}
                visible={fillDataVisible}
                onClose={() => {
                  setFillDataVisible(false);
                }}></AssignFillData>
            )}
          </>
        ),
      }));
  }, [sheetList, variablesData, props, btnType, fillDataVisible]);

  const handleOneKeyReport = async () => {
    const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
    message.loading('正在自动上报，请稍后', 0);

    await sleep(1000);
    try {
      await props.service.calculateAll();
      message.success('计算成功');

      await sleep(500);

      const errors = await props.service.validateAll();
      if (errors.some((e) => e.errorLevel === 'error')) {
        message.error('校验失败');
        return;
      } else if (errors.length > 0) {
        message.warning(`校验通过，但存在 ${errors.length} 个问题，请核实`);
      } else {
        message.success('校验成功');
      }
      setErrorCount(errors.length);

      window.dispatchEvent(new CustomEvent('submit-form'));
    } catch (error) {
      console.error(error);
    } finally {
      message.destroy();
    }
  };

  if (!loaded) return null;
  return (
    <div>
      <Tabs
        size={'small'}
        tabPosition="top"
        items={tabItems}
        addIcon
        tabBarExtraContent={
          props.allowEdit ? (
            <Space size={'small'}>
              {props.allowEdit && (
                <Button type="primary" size="small" ghost onClick={handleOneKeyReport}>
                  一键上报
                </Button>
              )}
              {assignTask?.metadata.nodeType == NodeType.Summary && (
                <Dropdown
                  trigger={['click']}
                  menu={{
                    items: [
                      {
                        key: 'summaryDirectChildren',
                        label: '直属下级汇总',
                        onClick: async () => {
                          try {
                            if (assignTask) {
                              const changes = await props.service.summary(
                                assignTask,
                                false,
                              );
                              if (changes.length > 0) {
                                message.success('汇总成功');
                              } else {
                                message.success('没有可汇总的数据');
                              }
                            } else {
                              message.error('汇总失败');
                            }
                          } catch (error) {
                            console.error(error);
                            message.error('汇总失败');
                          }
                        },
                      },
                      {
                        key: 'summaryLeafChildren',
                        label: '叶子节点汇总',
                        onClick: async () => {
                          try {
                            if (assignTask) {
                              const changes = await props.service.summary(
                                assignTask,
                                true,
                              );
                              if (changes.length > 0) {
                                message.success('汇总成功');
                              } else {
                                message.success('没有可汇总的数据');
                              }
                            } else {
                              message.error('汇总失败');
                            }
                          } catch (error) {
                            console.error(error);
                            message.error('汇总失败');
                          }
                        },
                      },
                    ],
                  }}>
                  <Button type="primary" size="small" ghost>
                    汇总
                  </Button>
                </Dropdown>
              )}
              <Dropdown
                trigger={['click']}
                menu={{
                  items: [
                    {
                      key: 'queryData',
                      label: '取数',
                      onClick: async () => {
                        try {
                          await getVariableData();
                          message.success('取数成功');
                        } catch (error) {
                          console.error(error);
                        }
                      },
                    },
                    {
                      key: 'dataSelect',
                      label: '数据选择',
                      disabled:
                        assignTask?.metadata.belongId === undefined &&
                        props.service.assignTask?.belongId === undefined,
                      onClick: async () => {
                        EditModal.showFormSelect({
                          form: props.form,
                          fields: props.fields,
                          belong: props.service.target,
                          multiple: false,
                          nodeBelong: assignTask?.metadata.belongId
                            ? assignTask?.metadata.belongId
                            : props.service.assignTask?.belongId,
                          onSave: (values) => {
                            if (values.length > 0 && props.info?.id) {
                              const form = values[0];
                              props.service.onDataSelect(form, props.form, props.info.id);
                            }
                          },
                        });
                      },
                    },
                    {
                      key: 'drill',
                      label: '属性值穿透',
                      disabled: assignTask?.metadata.nodeType !== NodeType.Summary,
                      onClick: async () => {
                        setBtnType('drill' + getUuid());
                      },
                    },
                    {
                      key: 'fill',
                      label: '数据补全',
                      disabled: assignTask?.metadata.name !== '浙江全省汇总',
                      onClick: () => {
                        setFillDataVisible(true);
                      },
                    },
                  ],
                }}>
                <Button type="primary" size="small" ghost>
                  <MoreOutlined />
                </Button>
              </Dropdown>
            </Space>
          ) : (
            assignTask && (
              <Space size={'small'}>
                {orgCtrl.user.companys
                  .find((com) => com.id === assignTask.metadata.belongId)
                  ?.hasSuperAuth() && (
                  <Button
                    type="primary"
                    size="small"
                    ghost
                    onClick={async () => {
                      await $confirm({
                        content: '发起变更后任务将会重置，确定要变更吗？',
                      });
                      try {
                        await assignTask?.change();
                        command.emitter('assign', 'refresh');
                      } catch (error) {
                        console.error(error);
                      }
                    }}>
                    变更
                  </Button>
                )}
                {validates.length > 0 && (
                  <Badge count={validates.length}>
                    <Button
                      type="primary"
                      size="small"
                      ghost
                      onClick={() => {
                        setValidateVisible(true);
                      }}>
                      校验说明
                    </Button>
                  </Badge>
                )}
              </Space>
            )
          )
        }
        activeKey={activeKey}
        onChange={setActiveKey}
      />
      {validateVisible && (
        <ValidationModal data={validates} onCancel={() => setValidateVisible(false)} />
      )}
    </div>
  );
};

export default WorkReportViewer;
